/***************************************************************************
 *   This file is part of KLabeler                                         *
 *   Copyright (C) 2010 by Luca Bellonda                                   *
 *   lbellonda _at_ gmail.com                                              *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "ConfigurationWindow.h"
#include "Utility.h"
#include "ui_configurationdialog.h"
#include <QInputDialog>
#include "ChooseProfile.h"

/*********************************************************************************
algorithm to choose the profile to edit:
-profile list
-current profile
 if there is no cuttent profile
  if there is no list, ask for creation, if so, use it else exit
  else ask to choose from list or create a new one else exit
***************************************************************************************/


#define TAG_COLUMNS (2)

ConfigurationWindow::ConfigurationWindow(klabeler::KLabelerApplication *application, TagProfile *profile, QWidget *parent) : QDialog(parent),
        ui(new Ui::ConfigurationDialog), _profileTypeChoice(this)
{
    _application = application ;
    _currentProfile = profile ;
    _currentProfileModified = false ;
    ui->setupUi(this);
    _profileTypeChoice.addButton(ui->radioCurrentActivity);
    _profileTypeChoice.addButton(ui->radioAllActivities);
    _profileTypeChoice.addButton(ui->radioActivitiesSet);
    ui->tagsList->setColumnCount(TAG_COLUMNS);
    ui->tagsList->horizontalHeader()->setVisible(false);
    ui->tagsList->verticalHeader()->setVisible(false);
    ui->tagsList->setShowGrid(false);
    ui->activities->setEnabled(false);

    _tagsCompleter = new QCompleter(this);
    _tagsCompleter->setCaseSensitivity(Qt::CaseInsensitive);
    ui->chooseTag->setCompleter(_tagsCompleter);
    ui->chooseTag->setEditable(true);

    setModal(true);
    setupData();
    setProfileData(_currentProfile);
}

ConfigurationWindow::~ConfigurationWindow()
{
    loseProfile(false);
    resetData();
    delete ui;
}


void ConfigurationWindow::resetData()
{
    //resetData(_profiles);
}

void ConfigurationWindow::resetData(QVector<TagProfile*> &profiles)
{
    /*
    foreach( TagProfile *profile, profiles ) {
        delete profile;
    }
    profiles.clear();
    */
}

void ConfigurationWindow::changeEvent(QEvent *e)
{
    QDialog::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void ConfigurationWindow::setupData()
{
    loadAllTags();
    //resetData(_profiles);
    /*QVector<TagProfile*> *profiles = _application->getConfigurationManager()->getProfilesList();
    if( NULL != profiles ) {
        int size = profiles->size();
        for (int i = 0; i < size; i++) {
            _profiles.append(profiles->at(i));
        }
        profiles->clear();
        delete profiles;
    }*/
    setProfileData(_currentProfile);
    //ui->profileList->clear();
    /*foreach( TagProfile *profile, _profiles ) {
        addProfileToCombo( profile );
    }
    if( _profiles.count()>0) {
        ui->profileList->setCurrentIndex( 0 );
     }*/
}
/*
int ConfigurationWindow::addProfileToCombo( TagProfile *profile )
{
    ui->profileList->addItem( profile->getName(), profile->getId() );
    return ui->profileList->count()-1;
}
*/
/*
void ConfigurationWindow::on_profileList_currentIndexChanged(int index)
{
    TagProfile *profile = getCurrentSelectedProfile();
    bool isValidProfile = ( NULL != profile ) ? true : false ;
    enableProfileUI(isValidProfile);
    if( !isValidProfile ) {
        ui->tagsList->clear();
        ui->activities->clear();
        return ;
    }
    if( _currentProfile && _currentProfileModified ) {
        if( !saveProfile( _currentProfile ) ) {
            Utility::error("Unable to save profile data");
        }
    }
    _currentProfile = profile;
    setProfileData(profile);
}
*/

void ConfigurationWindow::enableWidgets(const bool how)
{
    ui->name->setEnabled(how);
    ui->description->setEnabled(how);
    ui->activities->setEnabled(how);
    ui->tagsList->setEnabled(how);
    ui->radioAllActivities->setEnabled(how);
    ui->radioCurrentActivity->setEnabled(how);
    ui->radioActivitiesSet->setEnabled(how);
    ui->deleteProfile->setEnabled(how);
    ui->tagsList->setEnabled(how);
    ui->addActivity->setEnabled(how);
    ui->addTag->setEnabled(how);
    ui->chooseTag->setEnabled(how);
    ui->remActivity->setEnabled(false);
}

void ConfigurationWindow::setProfileData(TagProfile* profile)
{
    enableWidgets(NULL != profile);
    if (NULL == profile) {
        enableWidgets(false);
        return;
    }
    // TODO: enable widgets
    switch (profile->getType()) {
    case TagProfile::ALLACTIVITIES:
        ui->radioAllActivities->setChecked(true);
        break;
    case TagProfile::ONEACTIVITY:
        ui->radioCurrentActivity->setChecked(true);
        break;
    case TagProfile::ACTIVITIESSET:
        ui->radioActivitiesSet->setChecked(true);
        break;
    default:
        Utility::error("Invalid profile type");
        break;
    }
    ui->tagsList->clear();
    foreach(QString tag, profile->getTags()) {
        Utility::addTagToSet(ui->tagsList, tag);
    }
    ui->activities->clear();
    foreach(QString activity, profile->getActivities()) {
        ui->activities->addItem(activity);
    }
    ui->name->setText(profile->getName());
    ui->description->setText(profile->getDescription());
    ui->chkEnabled->setChecked(profile->isEnabled());
    enableWidgets(true);
}

void ConfigurationWindow::updateModel(TagProfile* profile)
{
    if (ui->radioAllActivities->isChecked()) {
        profile->setType(TagProfile::ALLACTIVITIES);
    } else if (ui->radioCurrentActivity->isChecked()) {
        profile->setType(TagProfile::ONEACTIVITY);
    } else { // TODO: default if ( ui->radioActivitiesSet->isChecked() )
        profile->setType(TagProfile::ACTIVITIESSET);
    }
    profile->resetTags();
    profile->resetActivities();
    QStringList tagList, activitiesList;
    Utility::getListSet(ui->activities, activitiesList);
    profile->setActivities(activitiesList);

    Utility::getTableSet(ui->tagsList, tagList);
    profile->setTags(tagList);

    profile->setName(ui->name->text());
    profile->setDescription(ui->description->text());
    profile->setEnabled(ui->chkEnabled->isChecked());
}

void ConfigurationWindow::on_radioActivitiesSet_toggled()
{
    bool isEnabled = ui->radioActivitiesSet->isChecked();
    ui->activities->setEnabled(isEnabled);
    ui->addActivity->setEnabled(isEnabled);
    ui->remActivity->setEnabled(isEnabled && (ui->activities->currentItem() != NULL));
}

void ConfigurationWindow::on_tagsList_cellChanged(int row, int column)
{
    if (NULL != _currentProfile) {
        _currentProfileModified = true ;
    }
}

void ConfigurationWindow::on_tagsList_cellClicked(int row, int column)
{
    if (NULL != _currentProfile) {
        _currentProfileModified = true ;
    }
}


void ConfigurationWindow::on_activities_itemSelectionChanged()
{
    ui->remActivity->setEnabled(ui->activities->isEnabled() && (ui->activities->currentItem() != NULL));
}

void ConfigurationWindow::on_addActivity_clicked()
{
    //aggiunge attivita sse non presente in lista
    bool isOk = false;
    QString activityName = "";

    activityName = QInputDialog::getText(this, APPL_SERVICE_NAME, i18n("Activity name:"),
                                         QLineEdit::Normal, "", &isOk);
    if (isOk && !activityName.isEmpty()) {
        QStringList activities = getActivities();

        foreach(QString act, activities) {
            if (act == activityName) {
                Utility::error(this, i18n("This activity is already enrolled."));
                return ;
            }
        }
        ui->activities->addItem(activityName);
        _currentProfileModified = true ;
    }
}

QStringList ConfigurationWindow::getActivities()
{
    QStringList list;
    int count = ui->activities->count();
    for (int i = 0 ; i < count ; i ++) {
        QListWidgetItem *item = ui->activities->item(i);
        if (NULL != item) {
            list.append(item->text());
        }
    }
    return list;
}


void ConfigurationWindow::on_remActivity_clicked()
{
    QListWidgetItem *item = ui->activities->currentItem();
    if (NULL != item) {
        int row = ui->activities->row(item);
        ui->activities->takeItem(row);
        delete item;
        _currentProfileModified = true ;
    }
}

void ConfigurationWindow::on_addTag_clicked()
{
    QString tag = ui->chooseTag->currentText() ;
    if (tag.length() > 0) {
        Utility::addTagToSet(ui->tagsList, tag);
        ui->chooseTag->clearEditText();
        _currentProfileModified = true ;
    }
}

void ConfigurationWindow::on_chooseTag_editTextChanged(const QString & text)
{
    ui->addTag->setEnabled(text.length() > 0);
}

void ConfigurationWindow::loadAllTags()
{
    _allTags = _application->getNepomukManager()->getAllTags();
    QStringListModel *model = new QStringListModel();
    model->setStringList(_allTags);
    _tagsCompleter->setModel(model);
}


void ConfigurationWindow::on_createProfile_clicked()
{
    if (!loseProfile(true)) {
        return;
    }
    TagProfile * newProfile = _application->getConfigurationManager()->createNewProfile();

    if (NULL != newProfile) {
        setProfile(newProfile);
    } else {
        Utility::error(i18n("Unable to create a new profile."));
    }
}
/*
TagProfile* ConfigurationWindow::getCurrentSelectedProfile()
{
    return
    int index = ui->profileList->currentIndex();
    if( index >= 0 ) {
        QVariant data = ui->profileList->itemData(index);
        QString id = data.toString();
        foreach( TagProfile *profile, _profiles ) {
            if( id == profile->getId() ) {
                return profile ;
            }
        }
    }
    return NULL;
}
*/
//---- TODO

void ConfigurationWindow::on_deleteProfile_clicked()
{
    if (NULL != _currentProfile) {
        if (Utility::askYN(this, i18n("Really delete the profile \"%1\"? Changes cannot be undone.").arg(_currentProfile->getName()))) {
            //TODO deleteProfile()
            setProfile(NULL);
        }
    }
}

bool ConfigurationWindow::saveProfile(TagProfile *profile)
{
    updateModel(_currentProfile);
    if (!_application->getConfigurationManager()->saveProfile(profile)) {
        Utility::error(i18n("Error saving profile data.")) ;
        return false;
    }
    return true ;
}

void ConfigurationWindow::on_chooseProfile_clicked()
{
    if (!loseProfile(true)) {
        return ;
    }
    TagProfile* profile = chooseProfile(this, _application);
    setProfile(profile);
    setProfileData(profile);
}

void ConfigurationWindow::on_name_textEdited(const QString &text)
{
    _currentProfileModified = true ;
}

void ConfigurationWindow::on_description_textEdited(const QString &text)
{
    _currentProfileModified = true ;
}

bool ConfigurationWindow::loseProfile(const bool isInterruptible)
{
    if (_currentProfile) {
        if (_currentProfileModified) {
            if (!saveProfile(_currentProfile)) {
                Utility::error(i18n("Error saving profile data.")) ;
                if (isInterruptible) {
                    return false;
                }
            }
        }
        delete _currentProfile ;
        _currentProfile = NULL ;
    }
    _currentProfileModified = false;
    if (isInterruptible) {
        enableWidgets(false);
    }
}

void ConfigurationWindow::setProfile(TagProfile* profile)
{
    _currentProfile = profile ;
    _currentProfileModified = false ;
    setProfileData(profile);
}

void ConfigurationWindow::accept()
{
    if (!_application->getConfigurationManager()->saveCurrentProfile(_currentProfile)) {
        Utility::error(NULL, i18n("Unable to save current profile informations."));
    }
    QDialog::accept();
}

//------------------------------------------------------------------------------
bool isAnyInList(QVector<TagProfile*> *vector)
{
    if (NULL == vector) {
        return false;
    }
    if (vector->size() > 0) {
        return true;
    }
    return false ;
}

TagProfile *getCurrentProfile(QVector<TagProfile*> *profiles)
{
    //TODO
    if (profiles->size() > 0) {
        return profiles->at(0);
    }
    return NULL ;
}

TagProfile* getProfile(klabeler::KLabelerApplication *application, QVector<TagProfile*> *profiles, QWidget *parent)
{
    if (NULL == profiles) {
        Utility::message(i18n("There are no profiles"));
        return NULL ;
    }
    TagProfile *currentProfile = getCurrentProfile(profiles);
    if (NULL == currentProfile) {
        if (isAnyInList(profiles)) {
            currentProfile = chooseProfile(parent, application);
            if (NULL == currentProfile) {
                return NULL ;
            }
        } else {
            if (Utility::askYN(parent, i18n("No profiles yet exists. Do you want to create a new one?"))) {
                currentProfile = application->getConfigurationManager()->createNewProfile();
                if (NULL == currentProfile) {
                    Utility::error(i18n("Unable to create a new profile."));
                    return NULL ;
                }
            }
        }
    }// a profile exists
    return currentProfile ;
}

bool showConfigurationDialog(klabeler::KLabelerApplication *application, QWidget *parent)
{
    QVector<TagProfile*> *profiles = application->getConfigurationManager()->getProfilesList();
    TagProfile* currentProfile = getProfile(application, profiles, parent);

    if (NULL != profiles) {
        int size = profiles->size();
        for (int i = 0; i < size; i++) {
            TagProfile* profile = profiles->at(i) ;
            if (profile != currentProfile) {
                delete profile ;
            }
        }
        profiles->clear();
        delete profiles;
    }

    ConfigurationWindow configurationDialog(application, currentProfile, parent);
    if (configurationDialog.exec() == QDialog::Accepted) {
        return true ;
    }
    return false ;
}
